home *** CD-ROM | disk | FTP | other *** search
/ SIGGRAPH 2002 Course Notes / SIGGRAPH 2002 - Course Notes - Disc 1.iso / pc / notes / 05 / supplemental_material / RNL_Source / pflare.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-07  |  29.0 KB  |  1,207 lines

  1. /* Copyright (c) 1998 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)psum.c 2.3 6/4/93 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  pflare.c - program to blur, vignette, and tint pictures
  9.  *
  10.  *     3/1998 - 3/1999
  11.  *     Paul Debevec
  12.  */
  13.  
  14. #include  <stdio.h>
  15. #include  <malloc.h>
  16. #include  <math.h>
  17. #include  <string.h>
  18.  
  19. #include  "color.h"
  20.  
  21. #include "resolu.h"
  22.  
  23. /* Function headers */
  24.  
  25. void xshift(int dx);
  26. void yshift(int dy);
  27. void dzoom();
  28. void giblur0(int twosigmasquared);
  29. void giblur0x(int twosigmasquared);
  30. void giblur0xy(int twosigmasquared);
  31. void giblur0yx(int twosigmasquared);
  32. void giblur0y(int twosigmasquared);
  33. void sepia(float cr,float cg,float cb);
  34. void multiplyimage(float cr,float cg,float cb);
  35. void scaleimage(float s);
  36. void vignette(float r0, float r1);
  37. void downsample();
  38. void upsample();
  39. void flip(COLOR **im);
  40. void zeroimage(COLOR **imzero);
  41. void copyimage(COLOR **imto, COLOR **imfrom);
  42. void accumulateimage(COLOR **imto, COLOR **imfrom, float scale);
  43. void undistort(double cx, double cy, double k1, double k2, double k3);
  44. void falloff(float r1, float r2, float g1, float g2, float b1, float b2);
  45. void sumthresh(int x0, int y0, int x1, int y1, float thresh);
  46. void invalidate(char *ppmfilename);
  47. void fixbug();
  48. void hardcode();
  49. void help();
  50.  
  51. int  xsiz, ysiz;
  52.  
  53. #define MAX(x,y) (((x)>(y))?(x):(y))
  54. #define MIN(x,y) (((x)<(y))?(x):(y))
  55.  
  56. char  *progname;
  57.  
  58. char  *fname;            /* the file names */
  59. FILE  *fptr;            /* the file pointers */
  60. COLOR  scale;            /* scaling factors */
  61. int  nfile;            /* number of files */
  62.  
  63. int DBM;
  64.  
  65. COLOR **imorig, **imin, **imout, **imfinal;
  66. COLOR black;
  67.  
  68. tabputs(s)            /* print line preceded by a tab */
  69.      char  *s;
  70. {
  71.   putc('\t', stdout);
  72.   fputs(s, stdout);
  73. }
  74.  
  75. main(argc, argv)
  76.      int  argc;
  77.      char  *argv[];
  78. {
  79.   double  d;
  80.   int  xres, yres;
  81.   int  an;
  82.   int ai0,ai1,ai2,ai3,ai4,ai5;
  83.   float af0,af1,af2,af3,af4,af5;
  84.   double ad0,ad1,ad2;
  85.   char * as0,as1,as2;
  86.   int accumulate = 0;
  87.  
  88.   progname = argv[0];
  89.  
  90.   DBM = 0;
  91.  
  92.   black[0] = 0;   black[1] = 0;   black[2] = 0; 
  93.   
  94.   if (argc < 2) {
  95.     fprintf(stderr, "%s: Please specify a file or '-' for stdin, or '-h' for help\n", progname);
  96.     quit(1);
  97.   }
  98.  
  99.   an = 1; // Set argument counter to 1
  100.  
  101.   if (strcmp("-h",argv[an]) == 0) {
  102.     fprintf(stderr, "Help on using pflare...\n");
  103.     help();
  104.   }
  105.  
  106.   if (argv[an][0] == '-') {   /* Read from stdin if first arg is '-' */
  107.     fname = "<stdin>";
  108.     fptr = stdin;
  109.   } else { /* Read from file */
  110.     fname = argv[1];
  111.     if ((fptr = fopen(argv[1], "r")) == NULL) {
  112.       fprintf(stderr, "%s: can't open file: %s\n",
  113.           progname, argv[1]);
  114.       quit(1);
  115.     }
  116.     an++;
  117.   }
  118.  
  119.   /* get header */
  120.   fputs(fname, stdout);
  121.   fputs(":\n", stdout);
  122.   getheader(fptr, tabputs);
  123.   /* get picture size */
  124.   if (fgetresolu(&xres, &yres, fptr) != (YMAJOR|YDECR)) {
  125.     if (DBM) fprintf(stderr, "%s: bad picture size\n", progname);
  126.     quit(1);
  127.   } else if (nfile == 0) {
  128.     xsiz = xres;
  129.     ysiz = yres;
  130.   } else if (xres != xsiz || yres != ysiz) {
  131.     if (DBM) fprintf(stderr, "%s: pictures are different sizes\n",
  132.         progname);
  133.     quit(1);
  134.   }
  135.  
  136.   if (DBM) fprintf(stderr,"Opened the file...\n");
  137.  
  138.   /* add new header info. */
  139.   printargs(argc, argv, stdout);
  140.   putchar('\n');
  141.   fputresolu(YMAJOR|YDECR, xsiz, ysiz, stdout);
  142.  
  143.   if (DBM) fprintf(stderr,"Wrote args...\n");
  144.  
  145.   allocateandread();
  146.  
  147.   if (DBM) fprintf(stderr,"Allocated and Read...\n");
  148.  
  149.   /************************************************/
  150.   /* Parse the rest of the command line arguments */
  151.   /************************************************/
  152.  
  153.   for (;an < argc; an++)
  154.     if (strcmp("-v",argv[an]) == 0) {
  155.       DBM = 1;
  156.       if (DBM) if (DBM) fprintf(stderr, "Verbose on...\n");
  157.     }
  158.     else if (strcmp("-gb",argv[an]) == 0) {
  159.       an++;
  160.       ai0 = atoi(argv[an]);
  161.       if (DBM) fprintf(stderr, "Gaussian Blurring %d...\n", ai0);
  162.       giblur0(ai0);
  163.     }
  164.     else if (strcmp("-xs",argv[an]) == 0) {
  165.       an++;
  166.       ai0 = atoi(argv[an]);
  167.       if (DBM) fprintf(stderr, "XShift %d...\n", ai0);
  168.       xshift(ai0);
  169.     }
  170.     else if (strcmp("-ys",argv[an]) == 0) {
  171.       an++;
  172.       ai0 = atoi(argv[an]);
  173.       if (DBM) fprintf(stderr, "YShift %d...\n", ai0);
  174.       yshift(ai0);
  175.     }
  176.     else if (strcmp("-gbx",argv[an]) == 0) {
  177.       an++;
  178.       ai0 = atoi(argv[an]);
  179.       if (DBM) fprintf(stderr, "Gaussian Blurring X %d...\n", ai0);
  180.       giblur0x(ai0);
  181.     }
  182.     else if (strcmp("-gby",argv[an]) == 0) {
  183.       an++;
  184.       ai0 = atoi(argv[an]);
  185.       if (DBM) fprintf(stderr, "Gaussian Blurring Y %d...\n", ai0);
  186.       giblur0y(ai0);
  187.     }
  188.     else if (strcmp("-gbxy",argv[an]) == 0) {
  189.       an++;
  190.       ai0 = atoi(argv[an]);
  191.       if (DBM) fprintf(stderr, "Gaussian Blurring X Y %d...\n", ai0);
  192.       giblur0xy(ai0);
  193.     }
  194.     else if (strcmp("-gbyx",argv[an]) == 0) {
  195.       an++;
  196.       ai0 = atoi(argv[an]);
  197.       if (DBM) fprintf(stderr, "Gaussian Blurring Y X %d...\n", ai0);
  198.       giblur0yx(ai0);
  199.     }
  200.     else if (strcmp("-gb1",argv[an]) == 0) {
  201.       an++;
  202.       ai0 = atoi(argv[an]);
  203.       if (DBM) fprintf(stderr, "Gaussian+ Blurring %d...\n", ai0);
  204.       giblur1(ai0);
  205.     }
  206.     else if (strcmp("-bb",argv[an]) == 0) {
  207.       an++;
  208.       ai0 = atoi(argv[an]);
  209.       if (DBM) fprintf(stderr, "Box Blurring %d...\n", ai0);
  210.       boxblur0(ai0);
  211.     }
  212.     else if (strcmp("-se",argv[an]) == 0) {
  213.       an++; af0 = atof(argv[an]);
  214.       an++; af1 = atof(argv[an]);
  215.       an++; af2 = atof(argv[an]);
  216.       if (DBM) fprintf(stderr, "Sepia %6.4f %6.4f %6.4f...\n", af0,af1,af2);
  217.       sepia(af0,af1,af2);
  218.     }
  219.     else if (strcmp("-mu",argv[an]) == 0) {
  220.       an++; af0 = atof(argv[an]);
  221.       an++; af1 = atof(argv[an]);
  222.       an++; af2 = atof(argv[an]);
  223.       if (DBM) fprintf(stderr, "Multiply %6.4f %6.4f %6.4f...\n", af0,af1,af2);
  224.       multiplyimage(af0,af1,af2);
  225.     }
  226.     else if (strcmp("-sc",argv[an]) == 0) {
  227.       an++; af0 = atof(argv[an]);
  228.       if (DBM) fprintf(stderr, "Scale %6.4f...\n", af0);
  229.       scaleimage(af0);
  230.     }
  231.     else if (strcmp("-vi",argv[an]) == 0) {
  232.       an++; af0 = atof(argv[an]);
  233.       an++; af1 = atof(argv[an]);
  234.       if (DBM) fprintf(stderr, "Vignette %6.4f %6.4f...\n", af0,af1);
  235.       vignette(af0,af1);
  236.     }
  237.     else if (strcmp("-fa",argv[an]) == 0) {
  238.       an++; af0 = atof(argv[an]);
  239.       an++; af1 = atof(argv[an]);
  240.       an++; af2 = atof(argv[an]);
  241.       an++; af3 = atof(argv[an]);
  242.       an++; af4 = atof(argv[an]);
  243.       an++; af5 = atof(argv[an]);
  244.       if (DBM) fprintf(stderr, "Falloff %6.4f %6.4f %6.4f %6.4f %6.4f %6.4f...\n", af0,af1,af2,af3,af4,af5);
  245.       falloff(af0,af1,af2,af3,af4,af5);
  246.     }
  247.     else if (strcmp("-ud",argv[an]) == 0) {
  248.       an++; af0 = atof(argv[an]);
  249.       an++; af1 = atof(argv[an]);
  250.       an++; af2 = atof(argv[an]);
  251.       an++; af3 = atof(argv[an]);
  252.       an++; af4 = atof(argv[an]);
  253.       if (DBM) fprintf(stderr, "Undistort %6.4f %6.4f %6.4f %6.4f %6.4f...\n", af0,af1,af2,af3,af4);
  254.       undistort(af0,af1,af2,af3,af4);
  255.     }
  256.     else if (strcmp("-ds",argv[an]) == 0) {
  257.       if (DBM) fprintf(stderr, "Downsample\n");
  258.       downsample();
  259.     }
  260.     else if (strcmp("-fb",argv[an]) == 0) {
  261.       if (DBM) fprintf(stderr, "FixBug\n");
  262.       fixbug();
  263.     }
  264.     else if (strcmp("-in",argv[an]) == 0) {
  265.       an++; as0 = argv[an];
  266.       if (DBM) fprintf(stderr, "Invalidate %s...\n", as0);
  267.       invalidate(as0);
  268.     }
  269.     else if (strcmp("-us",argv[an]) == 0) {
  270.       /* an++; af0 = atof(argv[an]); */
  271.       if (DBM) fprintf(stderr, "Upsample\n");
  272.       upsample();
  273.     }
  274.     else if (strcmp("-dz",argv[an]) == 0) {
  275.       if (DBM) fprintf(stderr, "Digital Zoom...\n");
  276.       dzoom();
  277.     }
  278.     else if (strcmp("-ac",argv[an]) == 0) {
  279.       an++; af0 = atof(argv[an]);
  280.       if (DBM) fprintf(stderr, "Accumulating %6.4f...\n", af0);
  281.       accumulate = 1;
  282.       accumulateimage(imfinal,imin,af0);
  283.       copyimage(imin,imorig);
  284.     }
  285.     else if (strcmp("-fl",argv[an]) == 0) {
  286.       if (DBM) fprintf(stderr, "Flipping...\n", ai0);
  287.       flip(imin);
  288.     }
  289.     else if (strcmp("-ya",argv[an]) == 0) {
  290.       if (DBM) fprintf(stderr, "Yanking...\n", af0);
  291.       copyimage(imin,imfinal);
  292.     }
  293.     else if (strcmp("-ze",argv[an]) == 0) {
  294.       if (DBM) fprintf(stderr, "Zeroing...\n", af0);
  295.       zeroimage(imfinal);
  296.     }
  297.     else if (strcmp("-ha",argv[an]) == 0) {
  298.       an++; ai0 = atoi(argv[an]);
  299.       if (DBM) fprintf(stderr, "Hard-Coded Operation...\n", af0);
  300.       hardcode();
  301.     }
  302.     else if (strcmp("-st",argv[an]) == 0) {
  303.       an++; ai0 = atoi(argv[an]);
  304.       an++; ai1 = atoi(argv[an]);
  305.       an++; ai2 = atoi(argv[an]);
  306.       an++; ai3 = atoi(argv[an]);
  307.       an++; af0 = atof(argv[an]);
  308.       if (DBM) fprintf(stderr, "SumThreshhold %d %d %d %d %6.4f...\n", ai0,ai1,ai2,ai3,af0);
  309.       sumthresh(ai0,ai1,ai2,ai3,af0);
  310.     }
  311.     else {
  312.       fprintf(stderr, "%s: Unknown command: %s\n", progname, argv[an]);
  313.       quit(1);
  314.     }
  315.  
  316.   if (!accumulate) copyimage(imfinal,imin);
  317.  
  318.   if (DBM) fprintf(stderr,"About to write file...\n");
  319.  
  320.   writeandfree();
  321.  
  322.   if (DBM) fprintf(stderr,"Quitting...\n");
  323.  
  324.   quit(0);
  325. }
  326.  
  327. swapimages() {
  328.   COLOR ** temp;
  329.  
  330.   temp = imin;
  331.   imin = imout;
  332.   imout = temp;
  333. }
  334.  
  335. allocateandread() {
  336.   int  y;
  337.  
  338.   imin  = (COLOR **)malloc(ysiz*sizeof(COLOR*));
  339.   imout = (COLOR **)malloc(ysiz*sizeof(COLOR*));
  340.   imorig = (COLOR **)malloc(ysiz*sizeof(COLOR*));
  341.   imfinal = (COLOR **)malloc(ysiz*sizeof(COLOR*));
  342.  
  343.   if (imin == NULL || imout == NULL) {
  344.     if (DBM) fprintf(stderr, "%s: out of memory\n", progname);
  345.     quit(1);
  346.   }
  347.  
  348.   for (y=0; y<ysiz; y++) {
  349.     imorig[y] = (COLOR *)malloc(xsiz*sizeof(COLOR));
  350.     if (freadscan(imorig[y], xsiz, fptr) < 0) {
  351.       if (DBM) fprintf(stderr, "%s: read error on file: %s\n",
  352.           progname, fname[0]);
  353.       quit(1);
  354.     }
  355.     imin[y] = (COLOR *)malloc(xsiz*sizeof(COLOR));
  356.     imout[y] = (COLOR *)malloc(xsiz*sizeof(COLOR));
  357.     imfinal[y] = (COLOR *)malloc(xsiz*sizeof(COLOR));
  358.   }
  359.  
  360.   copyimage(imin,imorig);
  361.   zeroimage(imfinal);
  362. }
  363.  
  364. writeandfree() {
  365.   int  y;
  366.  
  367.   for (y=0; y<ysiz; y++) {
  368.     if (fwritescan(imfinal[y], xsiz, stdout) < 0) {
  369.       if (DBM) fprintf(stderr, "%s: write error\n", progname);
  370.       quit(1);
  371.     }
  372.     free(imin[y]);
  373.     free(imout[y]);
  374.     free(imfinal[y]);
  375.   }
  376.   
  377.   free(imin);
  378.   free(imout);
  379.   free(imfinal);
  380. }
  381.  
  382. quit(code)        /* exit gracefully */
  383.      int  code;
  384. {
  385.   exit(code);
  386. }
  387.  
  388. /*
  389. int mkgaussian(float *gauss,float s2) {
  390.   int x;
  391.   int fsize = (int)(s2 * 4);
  392.  
  393.   for (x=0
  394.   gauss[x]=exp(-x*x/(2*S2))/sqrt(2*M_PI*S2);
  395. }
  396. */
  397.  
  398. void giblur0(int twosigsquared) {
  399.  
  400.   giblur0x(twosigsquared);
  401.   giblur0y(twosigsquared);
  402.  
  403. }
  404.  
  405. void giblur0x(int twosigsquared) {
  406.   int  fx, fy, y, i;
  407.   register int  x;
  408.   float scalefac;
  409.  
  410.   scalefac=1;
  411.   for (fx = 0; fx < twosigsquared; fx++)
  412.     scalefac *= 0.25;
  413.  
  414.   for (y = 0; y < ysiz; y++)
  415.     
  416.     /* Blur in X */
  417.     for (fx = 0; fx < twosigsquared; fx++) {
  418.       
  419.       copycolor(imout[y][0], imin[y][0]);
  420.       addcolor(imout[y][0], imin[y][0]);
  421.       addcolor(imout[y][0], imin[y][1]);
  422.  
  423.       copycolor(imout[y][xsiz-1], imin[y][xsiz-1]);
  424.       addcolor(imout[y][xsiz-1], imin[y][xsiz-1]);
  425.       addcolor(imout[y][xsiz-1], imin[y][xsiz-2]);
  426.  
  427.       for (x = 1; x < xsiz-1; x++) {
  428.     copycolor(imout[y][x], imin[y][x]);
  429.     addcolor(imout[y][x], imin[y][x]);
  430.     addcolor(imout[y][x], imin[y][x-1]);
  431.     addcolor(imout[y][x], imin[y][x+1]);
  432.       }
  433.       for (x = 0; x < xsiz; x++)
  434.     copycolor(imin[y][x], imout[y][x]);
  435.       
  436.     }
  437.   
  438.   /* Renormalize */
  439.   for (y = 0; y < ysiz; y++)
  440.     for (x = 0; x < xsiz; x++)
  441.       scalecolor(imin[y][x],scalefac);
  442. }
  443.  
  444. void giblur0y(int twosigsquared) {
  445.   int  fx, fy, y, i;
  446.   register int  x;
  447.   float scalefac;
  448.  
  449.   scalefac=1;
  450.   for (fx = 0; fx < twosigsquared; fx++)
  451.     scalefac *= 0.25;
  452.  
  453.   /* Blur in Y */
  454.   for (x = 0; x < xsiz; x++)
  455.     
  456.     for (fx = 0; fx < twosigsquared; fx++) {
  457.       
  458.       copycolor(imout[0][x], imin[0][x]);
  459.       addcolor(imout[0][x], imin[0][x]);
  460.       addcolor(imout[0][x], imin[1][x]);
  461.  
  462.       copycolor(imout[ysiz-1][x], imin[ysiz-1][x]);
  463.       addcolor(imout[ysiz-1][x], imin[ysiz-1][x]);
  464.       addcolor(imout[ysiz-1][x], imin[ysiz-2][x]);
  465.  
  466.       for (y = 1; y < ysiz-1; y++) {
  467.     copycolor(imout[y][x], imin[y][x]);
  468.     addcolor(imout[y][x], imin[y][x]);
  469.     addcolor(imout[y][x], imin[y-1][x]);
  470.     addcolor(imout[y][x], imin[y+1][x]);
  471.       }
  472.       for (y = 0; y < ysiz; y++)
  473.     copycolor(imin[y][x], imout[y][x]);
  474.       
  475.     }
  476.   
  477.   /* Renormalize */
  478.   for (y = 0; y < ysiz; y++)
  479.     for (x = 0; x < xsiz; x++)
  480.       scalecolor(imin[y][x],scalefac);
  481. }
  482.  
  483. void giblur0xy(int twosigsquared) {
  484.   int  fx, fy, y, i;
  485.   register int  x;
  486.   float scalefac;
  487.  
  488.   scalefac=1;
  489.   for (fx = 0; fx < twosigsquared; fx++)
  490.     scalefac *= 0.25;
  491.  
  492.   for (fx = 0; fx < twosigsquared; fx++) {
  493.     for (y = 1; y < ysiz-1; y++) {
  494.       for (x = 1; x < xsiz-1; x++) {
  495.     copycolor(imout[y][x], imin[y][x]);
  496.     addcolor(imout[y][x], imin[y][x]);
  497.     addcolor(imout[y][x], imin[y-1][x-1]);
  498.     addcolor(imout[y][x], imin[y+1][x+1]);
  499.       }
  500.     }
  501.     swapimages();
  502.   }
  503.   
  504.   /* Renormalize */
  505.   for (y = 0; y < ysiz; y++)
  506.     for (x = 0; x < xsiz; x++)
  507.       scalecolor(imin[y][x],scalefac);
  508. }
  509.  
  510. void giblur0yx(int twosigsquared) {
  511.   int  fx, fy, y, i;
  512.   register int  x;
  513.   float scalefac;
  514.  
  515.   scalefac=1;
  516.   for (fx = 0; fx < twosigsquared; fx++)
  517.     scalefac *= 0.25;
  518.  
  519.   for (fx = 0; fx < twosigsquared; fx++) {
  520.     for (y = 1; y < ysiz-1; y++) {
  521.       for (x = 1; x < xsiz-1; x++) {
  522.     copycolor(imout[y][x], imin[y][x]);
  523.     addcolor(imout[y][x], imin[y][x]);
  524.     addcolor(imout[y][x], imin[y+1][x-1]);
  525.     addcolor(imout[y][x], imin[y-1][x+1]);
  526.       }
  527.     }
  528.     swapimages();
  529.   }
  530.   
  531.   /* Renormalize */
  532.   for (y = 0; y < ysiz; y++)
  533.     for (x = 0; x < xsiz; x++)
  534.       scalecolor(imin[y][x],scalefac);
  535. }
  536.  
  537. giblur1(int twosigsquared) {
  538.   int  fx, fy, y, i;
  539.   register int  x;
  540.   float scalefac;
  541.   COLOR tempc;
  542.  
  543.   scalefac=1;
  544.   for (fx = 0; fx < twosigsquared; fx++)
  545.     scalefac *= 0.25;
  546.  
  547.   for (y = 0; y < ysiz; y++)
  548.     
  549.     /* Blur in X */
  550.     for (fx = 0; fx < twosigsquared; fx++) {
  551.       
  552.       copycolor(imout[y][0], imin[y][0]);
  553.       addcolor(imout[y][0], imin[y][0]);
  554.       addcolor(imout[y][0], imin[y][1]);
  555.  
  556.       copycolor(imout[y][xsiz-1], imin[y][xsiz-1]);
  557.       addcolor(imout[y][xsiz-1], imin[y][xsiz-1]);
  558.       addcolor(imout[y][xsiz-1], imin[y][xsiz-2]);
  559.  
  560.       for (x = 2; x < xsiz-2; x++) {
  561.     copycolor(imout[y][x], imin[y][x]);
  562.     addcolor(imout[y][x], imin[y][x]);
  563.     addcolor(imout[y][x], imin[y][x-1]);
  564.     addcolor(imout[y][x], imin[y][x+1]);
  565.     copycolor(tempc, imin[y][x-2]);
  566.     scalecolor(tempc, 0.1);
  567.     addcolor(imout[y][x], tempc);
  568.     copycolor(tempc, imin[y][x+2]);
  569.     scalecolor(tempc, 0.1);
  570.     addcolor(imout[y][x], tempc);
  571.       }
  572.       for (x = 0; x < xsiz; x++)
  573.     copycolor(imin[y][x], imout[y][x]);
  574.       
  575.     }
  576.   
  577.   /* Renormalize */
  578.   for (y = 0; y < ysiz; y++)
  579.     for (x = 0; x < xsiz; x++)
  580.       scalecolor(imin[y][x],scalefac);
  581.   
  582.   /* Blur in Y */
  583.   for (x = 0; x < xsiz; x++)
  584.     
  585.     for (fx = 0; fx < twosigsquared; fx++) {
  586.       
  587.       copycolor(imout[0][x], imin[0][x]);
  588.       addcolor(imout[0][x], imin[0][x]);
  589.       addcolor(imout[0][x], imin[1][x]);
  590.  
  591.       copycolor(imout[ysiz-1][x], imin[ysiz-1][x]);
  592.       addcolor(imout[ysiz-1][x], imin[ysiz-1][x]);
  593.       addcolor(imout[ysiz-1][x], imin[ysiz-2][x]);
  594.  
  595.       for (y = 2; y < ysiz-2; y++) {
  596.     copycolor(imout[y][x], imin[y][x]);
  597.     addcolor(imout[y][x], imin[y][x]);
  598.     addcolor(imout[y][x], imin[y-1][x]);
  599.     addcolor(imout[y][x], imin[y+1][x]);
  600.     copycolor(tempc, imin[y-2][x]);
  601.     scalecolor(tempc, 0.1);
  602.     addcolor(imout[y][x], tempc);
  603.     copycolor(tempc, imin[y+2][x]);
  604.     scalecolor(tempc, 0.1);
  605.     addcolor(imout[y][x], tempc);
  606.       }
  607.       for (y = 0; y < ysiz; y++)
  608.     copycolor(imin[y][x], imout[y][x]);
  609.       
  610.     }
  611.   
  612.   /* Renormalize */
  613.   for (y = 0; y < ysiz; y++)
  614.     for (x = 0; x < xsiz; x++)
  615.       scalecolor(imin[y][x],scalefac);
  616. }
  617.  
  618. #define  subcolor(c1,c2)    ((c1)[0]-=(c2)[0],(c1)[1]-=(c2)[1],(c1)[2]-=(c2)[2])
  619.  
  620. #define  lumcolor(c1)    (0.3*(c1)[0]+0.6*(c1)[1]+0.1*(c1)[2])
  621.  
  622. boxblur0(int twosigsquared) {
  623.   int  fx, fy, y, i;
  624.   register int  x;
  625.   float scalefac;
  626.   COLOR total;
  627.  
  628.   scalefac=1 / (float)(2*twosigsquared+1);
  629.  
  630.   for (y = 0; y < ysiz; y++) {
  631.     
  632.     /* Blur in X */
  633.     setcolor(total,0,0,0);
  634.     
  635.     for (x = 0; x < twosigsquared; x++)
  636.       addcolor(total, imin[y][x]);
  637.  
  638.     for (x = 0; x < twosigsquared; x++) {
  639.       addcolor(total, imin[y][x+twosigsquared]);
  640.       copycolor(imout[y][x], total);
  641.     }
  642.  
  643.     for (x = twosigsquared; x < xsiz-twosigsquared; x++) {
  644.       addcolor(total, imin[y][x+twosigsquared]);
  645.       subcolor(total, imin[y][x-twosigsquared]);
  646.       copycolor(imout[y][x], total);
  647.     }
  648.  
  649.     for (x = xsiz-twosigsquared; x < xsiz; x++) {
  650.       subcolor(total, imin[y][x-twosigsquared]);
  651.       copycolor(imout[y][x], total);
  652.     }
  653.  
  654.   }
  655.  
  656.   /* Renormalize and copy */
  657.   for (y = 0; y < ysiz; y++)
  658.     for (x = 0; x < xsiz; x++) {
  659.       scalecolor(imout[y][x],scalefac);
  660.       copycolor(imin[y][x],imout[y][x]);
  661.     }
  662.  
  663.   /* Blur in Y */
  664.   for (x = 0; x < xsiz; x++) {
  665.     
  666.     setcolor(total,0,0,0);
  667.     
  668.     for (y = 0; y < twosigsquared; y++)
  669.       addcolor(total, imin[y][x]);
  670.  
  671.     for (y = 0; y < twosigsquared; y++) {
  672.       addcolor(total, imin[y+twosigsquared][x]);
  673.       copycolor(imout[y][x], total);
  674.     }
  675.  
  676.     for (y = twosigsquared; y < ysiz-twosigsquared; y++) {
  677.       addcolor(total, imin[y+twosigsquared][x]);
  678.       subcolor(total, imin[y-twosigsquared][x]);
  679.       copycolor(imout[y][x], total);
  680.     }
  681.  
  682.     for (y = ysiz-twosigsquared; y < ysiz; y++) {
  683.       subcolor(total, imin[y-twosigsquared][x]);
  684.       copycolor(imout[y][x], total);
  685.     }
  686.  
  687.   }
  688.  
  689.   /* Renormalize and copy */
  690.   for (y = 0; y < ysiz; y++)
  691.     for (x = 0; x < xsiz; x++) {
  692.       scalecolor(imout[y][x],scalefac);
  693.       copycolor(imin[y][x],imout[y][x]);
  694.     }
  695. }
  696.  
  697. /* Flip an image top-to-bottom and left-to-right */
  698. void flip(COLOR **im) {
  699.   register int x, y;
  700.  
  701.   COLOR c;
  702.  
  703.   for (y = 0; y < ysiz/2; y++)
  704.     for (x = 0; x < xsiz; x++) {
  705.       copycolor(c, im[ysiz-y-1][xsiz-x-1]);
  706.       copycolor(im[ysiz-y-1][xsiz-x-1],im[y][x]);
  707.       copycolor(im[y][x], c);
  708.     }
  709.  
  710.   if (ysiz % 1 == 1) {  /* If there's an odd number of lines, do the middle one */
  711.     y = ysiz/2;
  712.     for (x = 0; x < xsiz/2; x++) {
  713.       copycolor(c, im[ysiz-y-1][xsiz-x-1]);
  714.       copycolor(im[ysiz-y-1][xsiz-x-1],im[y][x]);
  715.       copycolor(im[y][x], c);
  716.     }
  717.   }
  718.  
  719. }
  720.  
  721. void copyimage(COLOR **imto, COLOR **imfrom) {
  722.   register int  x;
  723.   register int  y;
  724.  
  725.   /* Copy */
  726.   for (y = 0; y < ysiz; y++)
  727.     for (x = 0; x < xsiz; x++) {
  728.       copycolor(imto[y][x],imfrom[y][x]);
  729.     }
  730. }
  731.  
  732. void zeroimage(COLOR **imzero) {
  733.   register int  x;
  734.   register int  y;
  735.   COLOR zero;
  736.  
  737.   setcolor(zero,0.0,0.0,0.0);
  738.  
  739.   /* Zero */
  740.   for (y = 0; y < ysiz; y++)
  741.     for (x = 0; x < xsiz; x++) {
  742.       copycolor(imzero[y][x],zero);
  743.     }
  744. }
  745.  
  746. void accumulateimage(COLOR **imto, COLOR **imfrom, float scale) {
  747.   register int  x;
  748.   register int  y;
  749.   COLOR temp;
  750.  
  751.   /* Copy */
  752.   for (y = 0; y < ysiz; y++)
  753.     for (x = 0; x < xsiz; x++) {
  754.       copycolor(temp,imfrom[y][x]);
  755.       scalecolor(temp,scale);
  756.       addcolor(imto[y][x],temp);
  757.     }
  758. }
  759.  
  760. void sepia(float cr,float cg,float cb) {
  761.   int  fx, fy, y, i;
  762.   register int  x;
  763.   float scalefac,lum;
  764.   COLOR sepiac;
  765.  
  766.   /* Renormalize and Copy */
  767.   for (y = 0; y < ysiz; y++)
  768.     for (x = 0; x < xsiz; x++) {
  769.       setcolor(sepiac,cr,cg,cb);
  770.  
  771.       lum = lumcolor(imin[y][x]);
  772.       scalecolor(sepiac,lum);
  773.       
  774.       copycolor(imin[y][x],sepiac);
  775.     }
  776. }
  777.  
  778. void multiplyimage(float cr,float cg,float cb) {
  779.   int  fx, fy, y, i;
  780.   register int  x;
  781.   float scalefac,lum;
  782.   COLOR multc;
  783.  
  784.   setcolor(multc,cr,cg,cb);
  785.  
  786.   /* Renormalize and Copy */
  787.   for (y = 0; y < ysiz; y++)
  788.     for (x = 0; x < xsiz; x++) {
  789.       multcolor(imin[y][x],multc);
  790.     }
  791. }
  792.  
  793. void scaleimage(float s) {
  794.   int  fx, fy, y, i;
  795.   register int  x;
  796.  
  797.   /* Renormalize and Copy */
  798.   for (y = 0; y < ysiz; y++)
  799.     for (x = 0; x < xsiz; x++) {
  800.       scalecolor(imin[y][x],s);
  801.     }
  802. }
  803.  
  804. /* move things one byte over to fix temporary bug in DKODAK */
  805. void fixbug() {
  806.   int  fx, fy, y, i;
  807.   register int  x;
  808.   COLOR c0;
  809.   COLOR c1;
  810.   COLOR cf;
  811.  
  812.   for (y = 0; y < ysiz; y++) {
  813.     for (x = 0; x < xsiz-1; x++) {
  814.       copycolor(c0,imin[y][x]);
  815.       copycolor(c1,imin[y][x+1]);
  816.  
  817.       cf[0] = c0[1];
  818.       cf[1] = c0[2];
  819.       cf[2] = c1[0];
  820.  
  821.       copycolor(imout[y][x],cf);
  822.     }
  823.  
  824.     cf[0]=c1[1]; cf[1]=c1[2]; cf[2]=c1[0];
  825.     copycolor(imout[y][x],cf);
  826.   }
  827.   copyimage(imin,imout);
  828. }
  829.  
  830. void sumthresh(int x0, int y0, int x1, int y1, float thresh) {
  831.   int x,y;
  832.   COLOR sum,maxb;
  833.   int area = 0;
  834.  
  835.   setcolor(sum,0,0,0);
  836.   setcolor(maxb,0,0,0);
  837.  
  838.   /* Calculate brightest pixel */
  839.   for (y = y0; y < y1; y++) {
  840.     for (x = x0; x < x1; x++) {
  841.       if (imin[ysiz-y-1][x][1] > maxb[1]) {
  842.     copycolor(maxb,imin[ysiz-y-1][x]);
  843.       }
  844.     }
  845.   }
  846.  
  847.   /* Calculate average of all pixels at least thresh * the max brightness */
  848.   for (y = y0; y < y1; y++) {
  849.     for (x = x0; x < x1; x++) {
  850.       if (imin[ysiz-y-1][x][1] > thresh*maxb[1]) {
  851.     addcolor(sum,imin[ysiz-y-1][x]);
  852.     area++;
  853.       }
  854.     }
  855.   }
  856.  
  857.   fprintf(stderr,"Sum %6.3f %6.3f %6.3f Area %d Average %6.3f %6.3f %6.3f\n",sum[0],sum[1],sum[2],area,sum[0]/(float)area,sum[1]/(float)area,sum[2]/(float)area);
  858.  
  859. }
  860.  
  861. void falloff(float r1, float r2, float g1, float g2, float b1, float b2) {
  862.   int  fx, fy, y, i;
  863.   register int  x;
  864.   float scalefac,lum;
  865.   COLOR boost;
  866.   float rr;
  867.   float a,t;
  868.  
  869.   float xr = (float)xsiz /2;
  870.   float yr = (float)ysiz /2;
  871.  
  872.   for (y = 0; y < ysiz; y++) {
  873.     for (x = 0; x < xsiz; x++) {
  874.  
  875.       /* Compute normalized squared radius */
  876.       rr = ((x-xr)*(x-xr) + (y-ysiz/2)*(y-ysiz/2)) / (xr*xr);
  877.  
  878.       boost[0] = ((rr*r2 + r1) * rr + 1.0);
  879.       boost[1] = ((rr*g2 + g1) * rr + 1.0);
  880.       boost[2] = ((rr*b2 + b1) * rr + 1.0);
  881.  
  882.       multcolor(imin[y][x],boost);
  883.     }
  884.   }
  885. }
  886.  
  887. void vignette(float r0, float r1) {
  888.   int  fx, fy, y, i;
  889.   register int  x;
  890.   float scalefac,lum;
  891.   double radius;
  892.   float reduce,rscale;
  893.   float a,t;
  894.   float bsiz;
  895.  
  896.   /* Renormalize and Copy */
  897.   for (y = 0; y < ysiz; y++)
  898.     for (x = 0; x < xsiz; x++) {
  899.  
  900.       radius = sqrt((x-xsiz/2)*(x-xsiz/2) + (y-ysiz/2)*(y-ysiz/2));
  901.  
  902.       if (radius > r0) {
  903.     if (radius < r1) {
  904.       t = 1.0 - (radius-r0)/(r1-r0);
  905.       a = t * 2 - 1;
  906.       reduce = (0.25 * M_PI + 0.5 * asin(a) + 0.5 * a * sqrt( 1 - a*a ))/(0.5 * M_PI);
  907.       scalecolor(imin[y][x],reduce);
  908.     } else {
  909.       setcolor(imin[y][x],0.0,0.0,0.0);
  910.     }
  911.       }
  912.     }
  913. }
  914.  
  915. void undistort(double cx, double cy, double k1, double k2, double k3) {
  916.   int  fx, fy, y, i;
  917.   register int  x;
  918.   float scalefac,lum;
  919.   COLOR c0,c1,c2,c3,black;
  920.   double radius;
  921.   float reduce,rscale;
  922.   float a,t;
  923.   float bsiz;
  924.  
  925.   int funsize;
  926.   double* distfun;
  927.   double* idistfun;
  928.   double r,rf,qxf,qyf;
  929.   int ri,qxi,qyi;
  930.  
  931.   int width = xsiz;
  932.   int height = ysiz;
  933.  
  934.   double px, py;
  935.   double qx, qy;
  936.  
  937.   funsize = 2 * MAX(height,width);
  938.   distfun = (double*)calloc(funsize,sizeof(double));
  939.   idistfun = (double*)calloc(funsize,sizeof(double));
  940.  
  941.   // Sample forward function
  942.   for (x=0;x<funsize;x++) {
  943.     r = 0.001 * (double)x;
  944.     distfun[x] = (double)x * (1 + r*r * (k1 + r*r*(k2 + r*r*k3)));
  945.   }
  946.  
  947.   // Resample for backward function
  948.   x = 0;
  949.   y = 0;
  950.   while (x<(funsize-1) && y<funsize) {
  951.     while (y<funsize && distfun[x+1] >= (double)y) {
  952.       idistfun[y] = (double)x + ((double)y - distfun[x]) / (distfun[x+1]-distfun[x]);
  953.       if (y) idistfun[y] /= (double)y;
  954.       else idistfun[y] = 1;
  955.       y++;
  956.     }
  957.     x++;
  958.   }
  959.   free(distfun);
  960.  
  961.   /* Perform Undistortion */
  962.   for (y = 0; y < ysiz; y++) {
  963.     for (x = 0; x < xsiz; x++) {
  964.  
  965.       px = (double)x - cx;
  966.       py = (double)y - cy;
  967.  
  968.       r = sqrt(px*px + py*py);
  969.       ri = (int)r;     // Linearly Interpolate
  970.       rf = r - (double)ri;
  971.  
  972.       if ((ri+1 < funsize)) {
  973.     qx = cx + px * ((1-rf)*idistfun[ri] + rf*idistfun[ri+1]);
  974.     qy = cy + py * ((1-rf)*idistfun[ri] + rf*idistfun[ri+1]);
  975.  
  976. /*        copycolor(imout[y][x], imin[(int)qy][(int)qx]);   - no bilerp*/
  977.  
  978.         /* Perform bilinear interpolation */
  979.     qxi = (int) qx;
  980.         qxf = qx - qxi;
  981.     qyi = (int) qy;
  982.         qyf = qy - qyi;
  983.  
  984.     /* Make sure point is not off other image boundary */
  985.     if ( (qxi >= 0) && (qxi < xsiz-1) && (qyi >= 0) && (qyi < ysiz-1) ) {
  986.       copycolor(c0,imin[qyi][qxi]);
  987.       scalecolor(c0,1-qxf);
  988.       scalecolor(c0,1-qyf);
  989.  
  990.       copycolor(c1,imin[qyi][qxi+1]);
  991.       scalecolor(c1,qxf);
  992.       scalecolor(c1,1-qyf);
  993.  
  994.       copycolor(c2,imin[qyi+1][qxi]);
  995.       scalecolor(c2,1-qxf);
  996.       scalecolor(c2,qyf);
  997.  
  998.       copycolor(c3,imin[qyi+1][qxi+1]);
  999.           scalecolor(c3,qxf);
  1000.       scalecolor(c3,qyf);
  1001.  
  1002.           copycolor(imout[y][x], c0);
  1003.           addcolor(imout[y][x], c1);
  1004.           addcolor(imout[y][x], c2);
  1005.           addcolor(imout[y][x], c3);
  1006.         }
  1007.         else copycolor(imout[y][x],black);
  1008.       }
  1009.     }
  1010.   }
  1011.  
  1012.   free(idistfun);
  1013.   copyimage(imin,imout);
  1014. }
  1015.  
  1016. void downsample() {
  1017.   int  fx, fy, y, i;
  1018.   register int  x;
  1019.   float scalefac,lum;
  1020.   double radius;
  1021.   float reduce,rscale;
  1022.   float a,t;
  1023.   float bsiz;
  1024.  
  1025.   /* Shrink */
  1026.   for (y = 0; y < ysiz/2; y++)
  1027.     for (x = 0; x < xsiz/2; x++) {
  1028.       copycolor(imout[y][x],imin[2*y][2*x]);
  1029.       addcolor(imout[y][x],imin[2*y][2*x+1]);
  1030.       addcolor(imout[y][x],imin[2*y+1][2*x+1]);
  1031.       addcolor(imout[y][x],imin[2*y+1][2*x]);
  1032.       scalecolor(imout[y][x],0.25);
  1033.     }
  1034.  
  1035.   swapimages();
  1036.   xsiz /= 2;
  1037.   ysiz /= 2;
  1038. }
  1039.  
  1040. void upsample() {
  1041.   register int  x, y;
  1042.  
  1043.   /* Expand */
  1044.   xsiz *= 2;
  1045.   ysiz *= 2;
  1046.   for (y = 0; y < ysiz/2; y++)
  1047.     for (x = 0; x < xsiz/2; x++) {
  1048.       copycolor(imout[2*y][2*x],imin[y][x]);
  1049.       copycolor(imout[2*y][2*x+1],imin[y][x]);
  1050.       copycolor(imout[2*y+1][2*x],imin[y][x]);
  1051.       copycolor(imout[2*y+1][2*x+1],imin[y][x]);
  1052.     }
  1053.   swapimages();
  1054.  
  1055.   giblur0(1);
  1056. }
  1057.  
  1058. void dzoom() {
  1059.   register int  x, y;
  1060.  
  1061.   for (y = 0; y < ysiz; y++)
  1062.     for (x = 0; x < xsiz; x++) {
  1063.       copycolor(imout[y][x],imin[(y+ysiz/2)/2][(x+xsiz/2)/2]);
  1064.     }
  1065.   swapimages();
  1066.  
  1067.   giblur0(1);
  1068. }
  1069.  
  1070. void xshift(int dx) {
  1071.   register int  x, y;
  1072.  
  1073.   for (y = 0; y < ysiz; y++) {
  1074.     for (x = 0; x < dx; x++) {
  1075.       copycolor(imout[y][x],black);
  1076.     }
  1077.     for (x = MAX(dx,0); x < MIN(xsiz+dx,xsiz); x++) {
  1078.       copycolor(imout[y][x],imin[y][x-dx]);
  1079.     }
  1080.     for (x = xsiz+dx; x < xsiz; x++) {
  1081.       copycolor(imout[y][x],black);
  1082.     }
  1083.   }
  1084.   swapimages();
  1085. }
  1086.  
  1087. void yshift(int dy) {
  1088.   register int  x, y;
  1089.  
  1090.   for (x = 0; x < xsiz; x++) {
  1091.     for (y = 0; y < dy; y++) {
  1092.       copycolor(imout[y][x],black);
  1093.     }
  1094.     for (y = MAX(dy,0); y < MIN(ysiz+dy,ysiz); y++) {
  1095.       copycolor(imout[y][x],imin[y-dy][x]);
  1096.     }
  1097.     for (y = ysiz+dy; y < ysiz; y++) {
  1098.       copycolor(imout[y][x],black);
  1099.     }
  1100.   }
  1101.   swapimages();
  1102. }
  1103.  
  1104. void hardcode() {
  1105.   downsample();
  1106.   downsample();
  1107.   downsample();
  1108.   giblur0(12);
  1109.   accumulateimage(imfinal,imin,0.1);
  1110.   giblur0(28);
  1111.   accumulateimage(imfinal,imin,0.05);
  1112.   copyimage(imin,imfinal);
  1113.   copyimage(imfinal,imin);
  1114.   
  1115.   xsiz *= 8;  ysiz *= 8;
  1116.   copyimage(imin,imorig);
  1117.   downsample();
  1118.   downsample();
  1119.   downsample();
  1120.   giblur0(3);
  1121.   accumulateimage(imfinal,imin,0.1);
  1122.   copyimage(imin,imfinal);
  1123.   upsample();
  1124.   upsample();
  1125.   copyimage(imfinal,imin);
  1126.  
  1127.   xsiz *= 2;  ysiz *= 2;
  1128.   copyimage(imin,imorig);
  1129.   downsample();
  1130.   giblur0(1);
  1131.   accumulateimage(imfinal,imin,0.75);
  1132.   copyimage(imin,imfinal);
  1133.   upsample();
  1134. }
  1135.  
  1136. void invalidate(char *ppmfilename) {
  1137.   
  1138.   int bpp;
  1139.   int i, x, y;
  1140.   char strbuf[100];
  1141.   unsigned char row[40960];
  1142.   int depth,width,height;
  1143.   FILE *image;
  1144.   int r,g,b;
  1145.   
  1146.   if( (image=fopen(ppmfilename,"r")) == NULL ) {
  1147.     if (DBM) fprintf(stderr,"Load_PPM: can't open input file %s\n",fname);
  1148.     return;
  1149.   }
  1150.   strcpy(strbuf,"#");while (strbuf[0] == '#') fgets(strbuf,100,image);
  1151.   if (strncmp(strbuf,"P6",2)==0)   depth = 3;
  1152.   else if (strncmp(strbuf,"Pf",2)==0)   depth = 4; // Floating point
  1153.   else depth = 1;
  1154.   strcpy(strbuf,"#");while (strbuf[0] == '#') fgets(strbuf,100,image);
  1155.   sscanf(strbuf,"%d %d",&width,&height);
  1156.   strcpy(strbuf,"#");while (strbuf[0] == '#') fgets(strbuf,100,image);
  1157.  
  1158.   // The last line contains the bits per channel info; we'll require 8
  1159.   sscanf(strbuf,"%d",&bpp);
  1160.   if (bpp != 255) {
  1161.     if (DBM) fprintf(stderr,"Read_PPM: Must use 8 bits per channel\n");
  1162.     return;
  1163.   }
  1164.  
  1165.   if (DBM) fprintf(stderr,"Size is %dx%d, %d channels.\n",width,height,depth);
  1166.  
  1167.   if (depth == 3) {
  1168.     for (y=0;y<height;y++) {
  1169.       fread(row,1,width * depth,image);
  1170.       for (x=0;x<width;x++) {
  1171.         unsigned char *pp = row + x * depth;
  1172.         /* SetRGBint(x,height - 1 - y,*pp,*(pp+1),*(pp+2)); */
  1173.     r = *pp; g = *(pp+1); b = *(pp+2);
  1174.     if (b == 255 && r == 0 && g == 0) {
  1175.       setcolor(imin[y][x],0,0,0);
  1176.     }
  1177.       }
  1178.     }
  1179.   }
  1180.   fclose(image);
  1181. }
  1182.  
  1183. void help() {
  1184.   fprintf(stderr,"\npflare - blur, vignette, and tint RADIANCE pictures\n\n");
  1185.   fprintf(stderr,"0\n");
  1186.   fprintf(stderr,"-gb n                Gaussian Blur, n=2*sigma^2\n");
  1187.   fprintf(stderr,"-gbx n               Gaussian Blur (X only)\n");
  1188.   fprintf(stderr,"-gby n               Gaussian Blur (Y only)\n");
  1189.   fprintf(stderr,"-bb n                Box Blur\n");
  1190.   fprintf(stderr,"-se r g b            Tint to color (r,g,b)\n");
  1191.   fprintf(stderr,"-mu r g b            Tint to color (r,g,b)\n");
  1192.   fprintf(stderr,"-sc s                Scale image by s)\n");
  1193.   fprintf(stderr,"-vi r0 r1            Vignette with falloff radii r0 and r1\n");
  1194.   fprintf(stderr,"-ud cx cy k0 k1 k2   Undistort\n");
  1195.   fprintf(stderr,"-ds                  Downsample\n");
  1196.   fprintf(stderr,"-in fn               Invalidate from ppm\n");
  1197.   fprintf(stderr,"-ac x                Accumulate\n");
  1198.   fprintf(stderr,"-ya                  Yank (copy ifinal in imin)\n");
  1199.   fprintf(stderr,"-ze                  Zero final image\n");
  1200.   fprintf(stderr,"-ha n                Hard-Coded Operation #n\n");
  1201.   fprintf(stderr,"-ac x                Sum with Threshhold\n");
  1202.   
  1203.   fprintf(stderr,"\n");
  1204.   exit(1);
  1205. }
  1206.  
  1207.